
/*
依赖multi
gurl:游戏后台唯一入口， http://xxx.yyy.com/branch/opensdk
rnet : 网络请求模块，rnet(url,data,callback) , 使用callback模式提高兼容性

*/


function gsdk(opts,rnet){
    if( !(this instanceof gsdk) ){
        return new gsdk(opts,rnet);
    }
    //系统配置
    let gurl = opts['url']||'';
    if(gurl[gurl.length - 1] == '/'){
        gurl = gurl.substr(0,gurl.length - 1);
    }
    //game master url
    this.gurl    = [gurl,opts['branch'],opts['opensdk']].join('/');
    console.log("妈的必然是这里有问题啊----------this.gurl:",this.gurl )

    //网络请求
    this.rnet      = rnet;
    this.branch   = opts['branch'];
    this.opensdk  = opts['opensdk'];

    this.game      = null;
    this.gzone     = new _gsdk_gzone(this);
    //本地存储器，必须包含 storage.get(key),storage.get(key,val)两个方法，设置空则不使用持久化
    this.storage = null;
    //游戏时间每日重置时间
    this.DAYRESET = 0;
}

gsdk.prototype.today = function(){
    let newDate,newTime = arguments[0] || Date.now();
    if(exports.reset > 0) {
        newTime = newTime - this.DAYRESET * 3600 * 1000;
    }
    newDate = new Date(newTime);
    newDate.setHours(this.DAYRESET,0,0,0);
    return newDate.getTime();
}
//封装错误信息
gsdk.prototype.error = function(err){
    let result;
    if(typeof err === 'string'){
        result = {"err":err,"ret":""}
    }
    else if(err instanceof Error){
        result =  {"err":err.message,"ret":err.stack}
    }
    else if(err.err){
        result =  {"err":err.err,"ret":err.ret||''}
    }
    else{
        result =  {"err":'error',"ret":err||''}
    }
    return Promise.reject(result);
}
//网络请求
gsdk.prototype.request = function(url,data){
    console.log("网络请求:-----------------url",url)
    if(typeof this.rnet !== 'function'){
        return this.error("gsdk.rnet not function");
    }
    return gsdk.promise(this.rnet,url,data).then(text=>{
        console.log("网络请求:-----------------text",text)
        let json;
        if(typeof text === 'object'){
            json = text;
        }
        else{
            json = JSON.parse(text);
        }

        if(json['err']){
            return Promise.reject(json);
        }
        else{
            return json;
        }
    })
}

gsdk.promise = function(name,...args) {
    console.log("------------1",name)
    console.log("------------2",...args)
    let fun;
    if(typeof name === 'function'){
        fun = name;
    }
    else if(this && typeof this[name] ==='function'){
        fun = this[name];
    }
    if(!fun ){
        console.log("------------3 throw error")
        throw new Error(`library.promise[${name}] not function`);
    }
    console.log("------------4")
    const promise_callback = (resolve, reject) =>function(err, ret) { if(err){ reject({'err':err,'ret':ret});  }  else {  resolve(ret); } }
    console.log("------------5")
    return new Promise((resolve,reject)=>{
        console.log("------------6")
        let handler = promise_callback(resolve,reject);
        args.push(handler);
        console.log("------------7")
        try {
            console.log("------------8",fun)
            fun.apply(this,args);
        } catch (e) {
            console.log("------------9")
            handler(e);
        }
    })
}



/* 模块初始化
return multi
使用multi.start() 开始执行
*/
gsdk._modules_initialize = function(){
    let keys = Object.keys(this.modules);
    let mtask = multi(keys,(k)=>{
        let v = this.modules[k];
        if(!this[k]){
            Object.defineProperty(this, k , { value: new _gsdk_memcache(this.app), writable: false, enumerable: true, configurable: false, });
        }
        return this.request(v['api'],v['data']||{}).then(ret=>{
            this[k].initialize(ret['ret'],ret['time']);
            return ret;
        })
    });
    mtask.breakOnError = true;
    return mtask; 
}



///////////////////////////////账号服务器//////////////////////////////
function _gsdk_gzone(app){
    this.app = app;
    this.account = null;
    //数据缓存
    this.modules = {
        'config':{'api':'/config/','name':'加载游戏配置'},
        'server':{'api':'/server/','name':'加载服务器列表'}
    };
    this.initialize = gsdk._modules_initialize.bind(this);
}

//后台通用请求接口
_gsdk_gzone.prototype.request = function(api){
    let url = [this.app.gurl,api].join("");
    let data = arguments[1]||{};
    console.log("后台通用请求接口:------------------url:",url)
    console.log("后台通用请求接口:------------------data:",data)
    return this.app.request(url,data||{});
}


//获取玩家认证信息
_gsdk_gzone.prototype.login = function(data){
    let api = '/login/'; 
    return this.request(api,data).then(result=>{
        this.account = result['ret'];    
        return result;
    })
}

//选择服务器
_gsdk_gzone.prototype.select = function(sid){
    if(!sid){
        return this.app.error("gzone.select sid empty");
    }
    if( !this.server.exist(sid) ){
        return this.app.error(`gzone.select[${sid}] not exist`);
    }
    //生成服务器信息
    this.app.game = new _gsdk_game(this.app,sid);
    return Promise.resolve(sid);
}


///////////////////////////////游戏服务器ucenter结束后开始执行//////////////////////////////
function _gsdk_game(app,sid){
    this.app = app;
    //账号&角色信息
    this.sid    = sid;        //当前选择服务器ID
    this.role   = null;     //当前角色信息
    this.roles  = [];       //玩家当前服角色列表
    this.cookie = null;
    
    this.modules = {
        //'item':{'api':'/getter/data/item','name':'加载道具信息'},
        //'daily':{'api':'/getter/data/daily','name':'加载日常数据'},
        'active':{'api':'/getter/data/active','name':'加载活动日志'},
        //'record':{'api':'/getter/data/record/','name':'加载成就数据'},
        //'task':{'api':'/getter/task/','name':'加载任务日志'},
        //'order':{'api':'/getter/order/','name':'加载订单信息'},
    };

    this.initialize = gsdk._modules_initialize.bind(this);
}
//游戏通用请求接口
_gsdk_game.prototype.request = function(api){
    if(!this.sid){
        return this.app.error("game sid empty");
    }
    console.log("游戏通用请求接口---------sid:",this.sid)
    let server = this.app.gzone.server.get(this.sid);
    if(!server){
        return this.app.error(`server[${this.sid}] not exist`);
    }
    let url = server['remote'] + '/s' + this.sid + api;
    console.log("游戏通用请求接口---------",url)
    let data = arguments[1]||{};
    if(this.cookie){
        data[this.cookie['key']] = this.cookie['val'];
    }
    console.log("游戏通用请求接口---------url:",url)
    console.log("游戏通用请求接口---------data:",data)
    return this.app.request(url,data);
}

//获取当前服务器信息
_gsdk_game.prototype.server = function(){
    if(!this.sid){
        return this.app.error("game sid empty");
    }
    let server = this.app.gzone.server.get(this.sid);
    return Promise.resolve(server);
}


//step 2.登录游戏服
_gsdk_game.prototype.login = function(){
    console.log("登录游戏服---------")
    if(!this.app.gzone.account['access']){
        return this.app.error("game.login access empty");
    }
    if(!this.sid){
        return this.app.error("game.login sid empty");
    }
    let api = '/login/'; 
    let data = arguments[0]||{};
    data['access'] = this.app.gzone.account['access'];
    console.log("登录游戏服---------data:",api)
    console.log("登录游戏服---------data:",data)
    return this.request(api,data).then(result=>{
        if( !result['ret'] ){
            console.log("登录游戏服error---------result:",result)
            return this.app.error("game login result error",result);
        }
        this.roles = result['ret']['roles']||[];
        this.cookie = result['ret']['cookie'];
        console.log("登录游戏服---------roles:",this.roles)
        console.log("登录游戏服---------cookie:",this.cookie)
        return this.roles;
    })
}
//step 2.x,创建新角色，非必须,但必须在step 1之后执行
_gsdk_game.prototype.create = function(){
    if(!this.cookie){
        return this.app.error("game.create cookie empty");
    }
    let api = '/role/create/'; 
    return this.request(api,arguments[0]).then(result=>{
        if( !result['ret'] ){
            return this.app.error("game register result error",result);
        }
        this.roles.push(result['ret']);
        return result['ret'];
    })
}

//step 3,选择角色进入游戏
_gsdk_game.prototype.select = function(uid){
    if(!this.cookie){
        return this.app.error("game.select cookie empty");
    }
    let api = '/role/select/'; 
    let data = arguments[1]||{};
    data['uid'] = uid;
    return this.request(api,data).then(result=>{
        if( !result['ret'] ){
            return this.app.error("game select result error",result);
        }
        this.role = new _gsdk_memcache(this.app);
        this.role.initialize(result['ret'],result['time']);
        return result['ret'];
    })
}


//step x,游戏通用发包，必须在step 3之后才能使用
_gsdk_game.prototype.send = function(api){
    if(!this.role){
        return this.app.error("game select role empty");
    }
    console.log("游戏通用发包，必须在step---------api:",api)
    return this.request(api,arguments[1]).then(result=>{
        //处理updater信息

        return result;
    })
}


//获取游戏配置
_gsdk_game.prototype.config = function(cid){
    let ret = [];
    if(!this.app.gzone.config.dataset){
        return ret;
    }
    let dataset = this.app.gzone.config.dataset;
    for(let k in dataset){
        let v = dataset[k];
        if( cid && v['cid'] != cid ){
            continue;
        }
        let c = this.filter(v);
        if(c){
            ret.push(v);
        }
    }
    return ret;
}
//过滤配置,必须进入游戏后才能调用
_gsdk_game.prototype.filter = function(){
    let config = Object.assign({},arguments[0]);
    //渠道限制
    if( config['sdk'] && config['sdk'] != this.app.opensdk ){
        return false;
    }
    //服务器限制,清理空配置
    if(config['sid'] && config['sid'].length > 0 && config['sid'].indexOf(this.sid) < 0) {
        return false;
    }
    //开发时间
    if( config['TType'] > 0 ){
        let baseTime;
        if(config['TType'] > 1){
            baseTime = this.role.get("time");
        }
        else{
            let server = this.app.server.get(this.sid);
            if(!server){
                return false;
            }
            baseTime = server['time'];
        }
        let STime = config['STime']||1,ETime = config['ETime']||1;
        let nowtime = this.app.today(baseTime);
        config['STime'] = nowtime + (STime - 1) * DAYMS;
        config['ETime'] = nowtime + ETime * DAYMS;
    }

    let nowTime = Date.now();
    if( config['STime']>0 && config['STime'] > nowTime ){
        return false;   //还没上架
    }
    if( config['ETime']>0 && config['ETime'] < nowTime ){
        return false;       //已经下架
    }
    return config;
}


///////////////////////////缓存模块////////////////////////////
function _gsdk_memcache(){
    this.time    = 0;
    this.dataset = null;
}
//获取缓存内容
_gsdk_memcache.prototype.get = function(key){
    if( !this.dataset || arguments.length == 0){
        return this.dataset;
    }
    else{
        return this.dataset[key]||0;
    }
}
//设置数据
_gsdk_memcache.prototype.set = function(key,val){
    if( !this.dataset ){
        throw new Error("gsdk.memcache not initialize but use set")
    }
    if(typeof key === 'object'){
        Object.assign(this.dataset,key);
    }
    else {
        this.dataset[key] = val;
    }
}

//判断是否存在
_gsdk_memcache.prototype.exist = function(key){
    if( !this.dataset ){
        return false;
    }
    else {
        return (key in this.dataset);
    }
}

//初始化dataset
_gsdk_memcache.prototype.initialize = function(data,time){
    this.time = time;
    this.dataset = data||{};
}


